#include "pch.h"
#include "test_list.h"

#ifdef _DEBUG
	#define MLD_MODULE "UnitTest"
	#include <mld/mld.hpp>
#endif




test_list::test_list()
	: m_seed(clock())
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




void test_list::operator()()
{
	test_size();
	test_construction();
	test_insertion();
	test_iteration();
	test_erase();
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void test_list::test_size()
{
	//
	// Size requirements of boostext::list
	//
	// The list itself must have the size one pointer
	// An iterator must have the size of one pointer
	// A bucket must have the size of 2 pointers and the value_type
	//

	ASSERT_EQUAL(sizeof(void*), sizeof(list));
	ASSERT_EQUAL(sizeof(void*), sizeof(list::iterator));
	ASSERT_EQUAL(sizeof(void*), sizeof(list::const_iterator));
	// list::node is a private class and cannot be exposed to the outside
	//ASSERT_EQUAL(sizeof(void*) * 2 + sizeof(value_type), sizeof(list::node));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void test_list::test_construction()
{
	//
	// Constructor: Default constructor
	//

	list l1;

	ASSERT_EQUAL(0, l1.size());
	ASSERT(l1.isEmpty() == true);
	ASSERT(l1.begin() == l1.end());


	//
	// Constructor: From an element that is copied #n times
	//

	const std::size_t numElements = 2;
	const value_type element = 5.0;

	list l2(element, numElements);
	ASSERT_EQUAL(numElements, l2.size());
	ASSERT(l2.begin() != l2.end());
	ASSERT(l2.isEmpty() == false);
	ASSERT_EQUAL(element, l2.first());


	//
	// Constructor: From a range of elements
	//

	const value_type values[]  = {1, 2, 3, 4, 5, 6};
	const std::size_t num = sizeof(values) / sizeof(value_type);

	list l3(&values[0], &values[0] + num);
	ASSERT_EQUAL(num, l3.size());
	ASSERT(l3.begin() != l3.end());
	ASSERT(l3.isEmpty() == false);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void test_list::test_insertion()
{
	const std::size_t numElements = 100;

	list l1;
	stdlist l2;

	fill(l1, numElements);
	fill(l2, numElements);
	equal(l2, l1);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void test_list::test_iteration()
{
	
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void test_list::test_erase()
{
	const std::size_t numElements = 100;

	list l1;
	stdlist l2;

	fill(l1, numElements);
	fill(l2, numElements);

	l1.pop_front();
	l2.pop_front();
	equal(l2, l1);

	list::iterator beginl1 = l1.begin();
	list::iterator endl1   = l1.begin();
	stdlist::iterator beginl2 = l2.begin();
	stdlist::iterator endl2   = l2.begin();
	std::advance(beginl1, 10);
	std::advance(endl1, 20);
	std::advance(beginl2, 10);
	std::advance(endl2, 20);

	l1.erase(beginl1, endl1);
	l2.erase(beginl2, endl2);
	equal(l2, l1);

	beginl1 = l1.begin();
	endl1   = l1.end();
	beginl2 = l2.begin();
	endl2   = l2.end();

	bool erase = false;
	while(beginl1 != endl1)
	{
		if(erase)
		{
			beginl1 = l1.erase(beginl1);
			beginl2 = l2.erase(beginl2);
		}
		else
		{
			++beginl1;
			++beginl2;
		}

		erase = !erase;
	}

	equal(l2, l1);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
